package com;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 序列化即是把对象写到流里面的过程；反序列化即是把对象从流中读取出来的过程。
 * 写在流里的是对象的一个拷贝，而原来的对象仍然在JVM里面。
 * 
 * 前提是对象以及对象内部所有用到的对象都是可序列化的，否则就需要考虑把那些不可序列化的对象
 * 标记为transient，从而把它排除到复制范围之外。然后使对象实现Serializable接口。把对象写入到
 * 一个流里（不用依赖于文件，直接暂存在内存中即可），在从流里读取出来，便得到了一个深复制的对象。
 * 
 */
public class DeepCloneTest {
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
	    
		Employer2 employer = new Employer2();
	    employer.setName("arthinking");
	    Employee2 employee = new Employee2();
	    employee.setName("Jason");
	    employee.setEmployer(employer);
	    //通过深复制创建employee2
	    Employee2 employee2 = (Employee2) employee.deepCopy();
	    employee2.getEmployer().setName("Jason");

	    System.out.println(employee.getEmployer().getName());
	    System.out.println(employee2.getEmployer().getName());
	}
}

class Employee2 implements Serializable{

    private static final long serialVersionUID = 3969438177161438988L;
    private String name;
    private Employer2 employer;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Employer2 getEmployer() {
        return employer;
    }
    public void setEmployer(Employer2 employer) {
        this.employer = employer;
    }
    /**
     * 实现深复制的方法
     */
    public Object deepCopy() throws IOException, ClassNotFoundException{
        //字节数组输出流，暂存到内存中
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //序列化
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        //反序列化
        return ois.readObject();
    }
}

class Employer2 implements Serializable{

    private static final long serialVersionUID = 1L;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}